import axios from 'axios'
import utils from '@/utils/index.js'

import type { Record } from '@/types/index'

export const defaultHost = ''
export const defaultTimeout = 60000

export function getHeaders() {
  return { sessionid: '' }
}

export interface RequestParams {
  method: 'GET' | 'POST'
  url: string
  headers?: Record
  data?: Record
  params?: Record
  timeout?: number
  transformRequest?: any[]
}
export interface MyRequestParams extends Omit<RequestParams, 'url'> {
  path?: string
  host?: string
  mock?: boolean
  showLoading?: boolean
}

export const request = (config: MyRequestParams) => {
  const { mock, ...newConfig } = config

  if (!mock) {
    return axiosRequest(newConfig)
  } else {
    return mockRequest(config.path, config.showLoading)
  }
}

export const axiosRequest = (config: MyRequestParams) => {
  const { path, host, showLoading, ...newConfig } = config
  const url = (host || defaultHost) + path
  const axiosConfig: RequestParams = {
    ...newConfig,
    url,
    headers: newConfig.headers || getHeaders(),
    timeout: newConfig.timeout || defaultTimeout
  }

  if (showLoading) setLoading(true)
  return new Promise((resolve, reject) => {
    axios(axiosConfig)
      .then((resp) => {
        // console.log('axios成功: ', resp)
        if (resp.status === 200) {
          const { result } = resp.data || {}
          if (result !== false) {
            resolve(resp.data)
          } else {
            const massage = resp.data.message || utils.obj.jsonStringify(resp.data)
            showError(massage)
            reject(resp.data)
          }
        }
      })
      .catch((error) => {
        console.log('axios-catch', error)
        const massage =
          error.response.data.message || error.response.data || utils.obj.jsonStringify(error)
        showError(`${error.response.status}: ${massage}`)
        reject(error.response.data)
      })
      .finally(() => {
        if (showLoading) setLoading(false)
      })
  })
}

// 全局接口loading
export const setLoading = (type: boolean) => {
  return type
}

// 全局错误流程
export const showError = (message: string) => {
  return message
  // uni.showModal({
  //   title: '提示',
  //   content: `${resp.data.message}`,
  //   success: ({ confirm, cancel }) => {
  //     // 不管确定取消，都执行
  //     callback(resp.data)
  //   }
  // })
}

export const mockRequest = (path?: string, showLoading?: boolean) => {
  if (showLoading) setLoading(true)
  return utils.func
    .sleep(200, 1000)
    .then(() => {
      if (path !== '/xxx') {
        /* 模拟成功 */
        const res = {
          result: 'true',
          message: '模拟请求成功'
        }
        return res
      } else {
        /* 模拟失败 */
        // const res = {
        //   result: 'true',
        //   message: '模拟请求失败'
        // }
        throw '模拟error'
      }
    })
    .finally(() => {
      if (showLoading) setLoading(false)
    })
}

//
export const get = (path: string, params: Record, showLoading = false, host = defaultHost) => {
  return request({ method: 'GET', path, params, showLoading, host })
}
export const post = (path: string, data: Record, showLoading = false, host = defaultHost) => {
  return request({ method: 'POST', path, data, showLoading, host })
}
export const getMock = (path: string, params: Record, showLoading = false, host = defaultHost) => {
  return request({ method: 'GET', path, params, showLoading, host, mock: true })
}
export const postMock = (path: string, data: Record, showLoading = false, host = defaultHost) => {
  return request({ method: 'POST', path, data, showLoading, host, mock: true })
}

// formData请求
export const postFormData = (
  path: string,
  data: Record,
  showLoading = false,
  host = defaultHost
) => {
  return request({
    method: 'POST',
    host,
    path,
    data,
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded', // multipart/form-data'
      ...getHeaders()
    },
    transformRequest: [
      function (data: Record) {
        return stringify(data)
      }
    ],
    showLoading
  })
}
// 将参数转换成功 formData 接收格式
function stringify(data: Record) {
  const formData = new FormData()
  for (const key in data) {
    // eslint-disable-next-line no-prototype-builtins
    if (data.hasOwnProperty(key)) {
      if (data[key]) {
        if (data[key].constructor === Array) {
          if (data[key][0]) {
            if (data[key][0].constructor === Object) {
              formData.append(key, JSON.stringify(data[key]))
            } else {
              data[key].forEach((item: any, index: number) => {
                formData.append(key + `[${index}]`, item)
              })
            }
          } else {
            formData.append(key + '[]', '')
          }
        } else if (data[key].constructor === Object) {
          formData.append(key, JSON.stringify(data[key]))
        } else {
          formData.append(key, data[key])
        }
      } else {
        if (data[key] === 0) {
          formData.append(key, '0')
        } else {
          formData.append(key, '')
        }
      }
    }
  }
  return formData
}

// 用于搜索的输入延迟自动请求
let timeout: any = null
export const debounce = (func: Function, wait = 500) => {
  // 清除定时器
  if (timeout !== null) clearTimeout(timeout)
  timeout = setTimeout(() => {
    func?.()
  }, wait)
}

export default {
  defaultHost,
  defaultTimeout,
  getHeaders,
  request,
  axiosRequest,
  setLoading,
  showError,
  mockRequest,
  get,
  post,
  getMock,
  postMock,
  postFormData,
  debounce
}
